Involver Developer Network : Food Magazine Recipe Contest
This page last changed on Aug 16, 2012 by jed.wheeler@involver.com.
In this chapter we'll develop a robust user-generated-content (UGC) application leveraging the flexible contest Feature Block. This feature enables rapid development of brand-able UGC experiences by abstracting away common developer concerns such as file uploads & moderation. The walkthrough builds on Chapter 5 - All about Forms - it assumes you are familiar with the signup_form Feature Block. After completing this chapter you'll be able to create complete contest experiences in SML. Food Magazine Recipe ContestFood Magazine is the premier lifestyle magazine for aspiring Chefs and foodies. They're looking for fan-submitted recipes to feature in their magazine and are offering fabulous prizes to the winners. The Recipe contest needs to do a few things to be successful: 1 - Contestants to be able to easily enter their recipes and upload high-quality pictures. Contest WorkflowBefore continuing it's important to familiarize ourselves with the workflow of a contest:
Let's get started!
{% contest name:"GoodFood Recipes" %} <h2>{{contest.title}}</h2> <p>Share your favorite recipes for a chance to be featured in food magazine and win a lifetime supply of sardines!</p> {% endcontest %}
The Contest is incomplete because we have not specified the entry form and corresponding success experience. Building the contest entry processThe contest entry and success partials are unique within SML in that it cannot be called directly with a render tag, it must be launched with a user click from the contest_form_link. Because the system maps data outputs for the contest form dynamically when that click happens, attempting to render it directly will break your contest's data export. Let's start by setting up our contest_form_link and then we'll set up the entry form and success page. Once completed, we'll have a functioning data submission system. The contest_form_linkFirst, we need to set up the contest feature block and the contest_form_link that launches our entry and success partials. {% contest name:"GoodFood Recipes" %} <h2>{{contest.title}}</h2> <p>Share your favorite recipes for a chance to be featured in food magazine and win a lifetime supply of sardines!</p> <p> {% contest_form_link entry_form_partial: "form" success_partial: "confirmation" %} Click here to enter {% endcontest_form_link %} </p> {% endcontest %}
— The contest_form sub-block
{% partial name:"form" %} {% contest_form %} <ul> <li><label>Name:</label> <input type="text" name="registration[name]" value="{{contest_user.name}}"></li> <li><label>Email:</label> <input type="text" name="registration[email]"></li> <li><label>City</label><input type="text" name="registration[city]" value="{{contest_user.current_location.city }}"/></li> <li><label>State or Province:</label> <input type="text" name="registration[state]" value="{{contest_user.current_location.region }}"></li> <li><label>Age: *</label> <input type="text" name="registration[age]"></li> <li><input type="checkbox" name="submission[terms]" value="I have read the terms" /> I have read and agree to the <a href="{{contest.rules_link}}">Terms and Conditions of the contest</a>.</li> <li><input type="submit" value="Submit"></p> <li>* You must be 18 years of age or older in order to enter</li> </ul> {% endcontest_form %} {% endpartial %} Notice that the contest_form sub-block contains the html fields in the contest entry form the same way the signup_form tags do for the signup_form feature block. The difference is that where signup_form is a standalone block that can export data directly, the contest_form is part of the larger contest feature block and is used to generate content items. It cannot be used independently and does not accept "name" or other attributes associated with stand-alone blocks. Contest Form
Contest Form Field Naming Rules
Contest Form Context VariablesDepending on how you configure your contest_form_link, you may have access to several context variables in the entry form. For our purposes we're going to assume that the authorization_timing attribute is set to "on_show_form" (the default) so we have access to the context variable.
Contest Form ValidationValidation with contest forms works exactly the same as it does with signup forms, the only difference is the naming convention for the fields. Now that we know the basics let's get a bit more fancy. We'll add an {% unless %} statement in to hide the registration information for folks who've already submitted one entry and are in the process of submitting a second or third. The statement {% unless contest_user_is_registered %} simply tells the system that if the current user has already registered the content wrapped in that statement will not be shown. {% partial name:"form" %} {% contest_form rules_var:"entryValidation" %} <h2>Entry Form</h2> <ul> {% unless contest_user_is_registered %} <li><label>Name:</label> <input type="text" name="registration[name]" value="{{contest_user.name}}"></li> <li><label>Email:</label> <input type="text" name="registration[email]"></li> <li><label>City</label><input type="text" name="registration[city]" value="{{contest_user.current_location.city }}"/></li> <li><label>State or Province:</label> <input type="text" name="registration[state]" value="{{contest_user.current_location.region }}"></li> <li><label>Age: *</label> <input type="text" name="registration[age]"></li> {% endunless %} <li>Category: <br/> <select name="submission[contest_tags]"> <option value="*,breakfast">Breakfast</option> <option value="*,lunch">Lunch</option> <option value="*,dinner">Dinner</option> <option value="*,dessert">Dessert</option> </select></li> <li><label>Recipe Name:</label><input type="text" name="submission[recipe_name]" /></li> <li><label>Recipe:</label><br/> <textarea type="text" name="submission[recipe]"/></li> <li><label>Story</label><br/> <textarea type="text" name="submission[story]"/></li> <li><label>Main Photo:</label> {% image_upload_field name:'submission[photo_1]' %}</li> <li><label>(Optional) Additional Photos:</label> <ul> <li>{% image_upload_field name:'submission[photo_2]' %}</li> <li>{% image_upload_field name:'submission[photo_3]' %}</li> <li>{% image_upload_field name:'submission[photo_4]' %}</li> </ul> </li> <li><input type="checkbox" name="submission[terms]" value="I have read the terms" /> I have read and agree to the <a href="{{contest.rules_link}}">Terms and Conditions of the contest</a>. Information will be used in accordance with our <a href="{{contest.privacy_policy_url}}">privacy policy</a></li> <li><input type="submit" value="Submit"></li> <li>* You must be 18 years of age or older in order to enter</li> </ul> <script> var entryValidation = { 'registration[name]': {required: true}, 'registration[email]': {required: true}, 'registration[city]': {required: true}, 'registration[state]': {required: true}, 'registration[age]': {required: true, min:18}, 'registration[rules]': {required: true}, 'submission[photo_1]': {required: true}, 'submission[recipe_name]': {required: true}, 'submission[recipe]': {required: true}, 'submission[story]': {required: true} }; </script> {% endcontest_form %} {% endpartial %} Building custom arrays with contest_form fieldsNotice the naming convention on the images. By using the . notation in the names we're able to build a custom array of all the photos on the contest entry. We'll be able to output those images either individually by calling their names explicitly (contest_entry.submission.photos.1 , for instance) or as an array by calling contest_entry.submission.photos within a for loop. That ability to call the set of photos as a custom array is going to be very useful for us as we set up the rest of the app. The Success PageOnce the user has submitted their data we need to show them a confirmation message to let them know we have received their data. Success Message Context Variables You have access to the same context variables above in addition to:
{% partial name: "confirmation" %} <h2>Success!</h2> <h3>Thank you, {{ contest_entry.registration.name }} for submitting your entry.</h3> <p>Email: {{ contest_entry.registration.email }}</p> <p>{{contest_entry.submission.recipe_name}}:</p> <div class="recipe">{{contest_entry.submission.recipe | newline_to_br }}</div> <p>Story:</p> <div class="recipe">{{contest_entry.submission.story | newline_to_br }}</div> <p>Main Photo of your recipe: {{ contest_entry.submission.photo_1 | img_tag }}</p> {% endpartial %} GalleryNow comes the fun part. Let's display accepted entries in a gallery view.
ModerationModerating your contest entries is accomplished via Involver's Audience Management Platform (AMP).
Contest entries can be one of the following states:
To change the state of the entry, simply click the corresponding icon to toggle the state. If you would like to update the state for a number of entries, select the entries using the check box and then choose and update action from the "Actions..." select box in the upper right corner. Custom OrderingLet's add pagination and update our gallery to enable custom ordering. We've done this several times at this point but more practice never hurt anyone. While we're at it, let's add voting. It's worth noting here that because this is a contest we cannot use the facebook_like tag on our entries because doing so would violate Facebook's Terms of Service for contests. Instead we'll use the content_vote tag to allow users to pick their favorites from among the entries submitted by their peers. At this time, content_vote does not support restricting the number of items that a person can vote for but you can restrict how frequently they can vote for any single item by using the cookie_days attribute.
Generating and sharing links to a specific contest entryIn many cases you'll need users to be able to share a link to a specific contest entry. After all, folks are much more likely to share if doing so increases their own chance of winning then if doing so just promotes your contest as a whole. There are two different methods to build this type of functionality in SML. In the first approach, you would actually have a unique page for each entry in the contest. In keeping with the structure of the Open Graph, each SML contest entry has its own unique dynamically generated url. We create these urls using Canvas Pages and any votes, likes, etc will be tracked to those unique urls. You can use SML to customize the look of those canvass pages and display the individual entries there, along with social functionality like comments, shares, ratings, and whatever else you need to power your app. Here's an example of how that would work: Using Canvass Pages{% partial name: "gallery" %} {% paginate contest.contest_entries per_page:6 order:order_by keywords:category %} {% for entry in contest_entries %} <h4><a href="{{entry.contest_entry_canvas_page_url}}">{{ entry.submission.recipe_name }}</a></h4> <p>Submitted by {{ entry.registration.name }}</p> <a href="{{entry.contest_entry_canvas_page_url}}">{{ entry.submission.photo_1 | resize_to: "200" | img_tag }}</a> {% content_vote entry %} {% endfor %} {{ pagination_links }} {% endpaginate %} {% endpartial %} and <!-- canvas Page for individual entry --> <div class="entryBox"> <div class="back"><a href="{{ application_url }}">Go back to {{contest.title}}</a></div> <h3>{{contest_entry.submission.title}} by {{contest_entry.registration.name}}</a> {% partial name:"bigPhoto" %} {{big | img_tag}} {% endpartial %} <div id="bigPhoto"> {% render partial:"bigPhoto" big:contest_entry.submission.photo_1 %} </div> <ul> {% for photo in contest_entry.submission.photos %} <li>{% ajax_link partial:"bigPhoto" div_id:"bigPhoto" big:photo %}{{photo | resize_to:"200"}}{% endajax_link %}</li> {% endfor %} </ul> <div class="recipe"> <h4>{{contest_entry.submission.recipe_name}}</h4> <div class="social"> <div class="votes">{% content_vote contest_entry %}</div> <div class="share">{% share contest_entry href:contest_entry.contest_entry_canvas_url %}</div> </div> {{contest_entry.submission.recipe | newline_to_br }} </div> <div class="recipe_story"> <p>The story behind {{contest_entry.submission.recipe_name}}:</p> {{contest_entry.submission.story | newline_to_br }} </div> <div class="comments"> {% facebook_comments contest_entry %} </div> <div class="back"><a href="{{ application_url }}">Go back to {{contest.title}}</a></div> </div> The changes to the pagination of the entry gallery in the first section of code add links to the unique canvas pages to each item in the gallery. Adding the code in the second section to the "Canvas Page SML"" field in the contest configuration will configure that page so when they arrive they'll see a gallery of images associated with that entry, the recipe, the story behind it, and have the opportunity to vote, share, and comment on the entry. In this model, each users entry exists on a page of its own and users who arrive on these entry pages need to click the "back to contest" link at the top and bottom of the page to see your contest. That arguably provides the best possible user experience for the people posting the entries, but doesn't necessarily provide the best ROI for you. The second option, which we recommend for most use cases, is to use a partial and load the single-entry view either in line or in a popup on your main contest page. Using page_params_link to share a single entry.In this model you'd start by building a featured item display in a partial <!-- inline-display for individual entry --> {% partial name:"featureBox" %} <div class="entryBox"> <h3>{{featuredItem.submission.title}} by {{featuredItem.registration.name}}</a> {% partial name:"bigPhoto" %} {{big | img_tag}} {% endpartial %} <div id="bigPhoto"> {% render partial:"bigPhoto" big:featuredItem.submission.photos.first %} </div> <ul> {% for photo in featuredItem.submission.photos %} <li>{% ajax_link partial:"bigPhoto" div_id:"bigPhoto" big:photo %}{{photo | resize_to:"200"}}{% endajax_link %}</li> {% endfor %} </ul> <div class="recipe"> <h4>{{featuredItem.submission.recipe_name}}</h4> <div class="social"> {% capture featuredURL %}{% page_params_link featuredItemId:featuredItem.id %}{% endcapture %} <div class="votes">{% content_vote featuredItem %}</div> <div class="share">{% share featuredItem href:featuredURL %}</div> </div> {{featuredItem.submission.recipe | newline_to_br }} </div> <div class="recipe_story"> <p>The story behind {{featuredItem.submission.recipe_name}}:</p> {{featuredItem.submission.story | newline_to_br }} </div> <div class="comments"> {% facebook_comments featuredItem %} </div> </div> {% endpartial %} And your paginated entry gallery would look something like this: <div id="featureBox"> {% if page_params_link.featuredItemId.size >0 %} {% get_content_item myItem content_item_id:page_params.featuredItemId %} {% render partial:"featureBox" featuredItem:myItem %} {{# checks if the page_params_link was used and, if so, grabs the id of the item that was shared, calls that content item, and pushes it into the featured item display }} {% elsif contest.contest_entries.size > 0 %} {% render partial:"featureBox" featuredItem:contest.contest_entries.first %} {{# shows the newest item as the featured item}} {% else %} There are no entries in this contest yet. Why not be the first? {% endif %} </div> {% partial name: "gallery" %} {% paginate contest.contest_entries per_page:6 order:order_by keywords:category %} {% for entry in contest_entries %} <h4>{% ajax_link partial:"featureBox" featuredItem:entry div_id:"featured" %}{{ entry.submission.recipe_name }}{% endajax_link %}</h4> <p>Submitted by {{ entry.registration.name }}</p> {% ajax_link partial:"featureBox" featuredItem:entry div_id:"featured" %}{{ entry.submission.photos.first | resize_to: "200" | img_tag }}{% endajax_link %} {% content_vote entry %} {% endfor %} {{ pagination_links }} {% endpaginate %} {% endpartial %} You might also add a bit of code to your success notification to allow people who've just entered your contest to share their entry right away {% partial name: "confirmation" %} <h2>Success!</h2> <h3>Thank you, {{ contest_entry.registration.name }} for submitting your entry.</h3> <p>Why not <a href="#" class="share">share</a> your recipe with your friends?</p> <p>Email: {{ contest_entry.registration.email }}</p> <p>Recipe:</p> <div class="recipe">{{contest_entry.submission.recipe | newline_to_br }}</div> <p>Story:</p> <div class="recipe">{{contest_entry.submission.story | newline_to_br }}</div> <p>Main Photo of your recipe: {{ contest_entry.submission.photos.1 | img_tag }}</p> {% if contest_entry.submission.photos.size > 1 %} <div class="photos"> <p>Additional photos:</p> <ul class="photo list"> {% for photo in contest_entry.submission.photos offset:1 %} <li>{{ photo | img_tag }}</li> {% endfor %} </ul> {% endif %} </div> {% capture featuredURL %}{% page_params_link featuredItemId:contest_entry.id %}{% endcapture %} <script> $(document).ready(function() { $('a.share').click(function(event) { sml.ui.Facebook.share({ user_message_prompt: "What is on your mind?", attachment: { name: '{{contest_entry.submission.recipe_name}}', caption: 'A delicious recipe by {{contest_entry.registration.name}}', href: '{{ shareURL }}', description: '{{contest_entry.submission.recipe | truncate::120}}', media: [{ type: 'image', src: '{{contest_entry.submission.photos.first}}', href: '{{ featuredURL }}' }] }, action_links: [{ text: 'Visit My Page', href: '{{ featuredURL }}' }], success: function(post_id) { sml.log("Success!"); }, error: function() { sml.log("Error! "); } }); }) }) </script> {% endpartial %} Setting automatic activation and de-activation of your contestYou can show or hide your contest according to any criteria you deem appropriate by setting a simple editable_setting and running if logic against its value. For instance {% editable_setting contest_is_active type:"boolean" default:true %} {% if contest_is_active %} <p> {% contest_form_link entry_form_partial:"form" success_partial:"confirmation" %} Click here to enter {% endcontest_form_link %} </p> {% else %} <p>We're sorry, this contest is no longer active</p> {% endif %} Would allow you to turn the entry link on and off by toggling the value of the editable setting "Contest is active" in your settings tab. But what if you want to automate the change so that it can happen at midnight and you won't have to be awake? Of course, way back in Chapter 2 we looked at doing this by capturing the now variable and comparing its value to a hard-coded unix time stamp. That's certainly an option here. But you could also use the contest.activated_at and contest.expired_at context variables (set in the contest config) to compare to 'now'. {% capture start %}{{contest.activated_at | date:"%s"}}{% endcapture %} {% capture end %}{{contest.expired_at | date:"%s"}}{% endcapture %} {% capture whatTime %}{{now | date:"%s"}}{% endcapture %} {% if start < whatTime and end > whatTime %} <p> {% contest_form_link entry_form_partial:"form" success_partial:"confirmation" %} Click here to enter {% endcontest_form_link %} </p> {% elsif start > whatTime %} The {{contest.title}} launches in {{start | count_down_to }}! Come back soon! {% elsif end < whatTime %} <p>We're sorry, {{contest.title}} is no longer active. Check out all the amazing recipes our fans submitted and try one at home tonight!</p> {% endif %} Congratulations, you now have a fully functional contest! Completed project code{% partial name: "form" %} {% contest_form rules_var:"entryValidation" %} <h2>Entry Form</h2> <ul> {% unless contest_user_is_registered %} <li><label>Name:</label> <input type="text" name="registration[name]" value="{{contest_user.name}}"></li> <li><label>Email:</label> <input type="text" name="registration[email]"></li> <li><label>City</label><input type="text" name="registration[city]" value="{{contest_user.current_location.city }}"/></li> <li><label>State or Province:</label> <input type="text" name="registration[state]" value="{{contest_user.current_location.region }}"></li> <li><label>Age: *</label> <input type="text" name="registration[age]"></li> {% endunless %} <li>Category: <br/> <select name="submission[contest_tags]"> <option value="*,breakfast">Breakfast</option> <option value="*,lunch">Lunch</option> <option value="*,dinner">Dinner</option> <option value="*,dessert">Dessert</option> </select></li> <li><label>Recipe Name:</label><input type="text" name="submission[recipe_name]" /></li> <li><label>Recipe:</label><br/> <textarea type="text" name="submission[recipe]"></li> <li><label>Story</label><br/> <textarea type="text" name="submission[story]"></li> <li><label>Main Photo:</label> {% image_upload_field name:'submission[photos.1]' %}</li> <li><label>(Optional) Additional Photos:</label> <ul> <li>{% image_upload_field name:'submission[photos.2]' %}</li> <li>{% image_upload_field name:'submission[photos.3]' %}</li> <li>{% image_upload_field name:'submission[photos.4]' %}</li> </ul> </li> <li><input type="checkbox" name="submission[terms]" value="I have read the terms" /> I have read and agree to the <a href="{{contest.rules_link}}">Terms and Conditions of the contest</a>. Information will be used in accordance with our <a href="{{contest.privacy_policy_url }}">Privacy Policy</a>.</li> <li><input type="submit" value="Submit"></p> <li>* You must be 18 years of age or older in order to enter</li> </ul> {% endcontest_form %} <script> var entryValidation = { 'registration[name]': {required: true}, 'registration[email]': {required: true}, 'registration[city]': {required: true}, 'registration[state]': {required: true}, 'registration[age]': {required: true, min:18}, 'registration[rules]': {required: true}, 'submission[photos.1]': {required: true}, 'submission[recipe_name]': {required: true}, 'submission[recipe]': {required: true}, 'submission[story]': {required: true} }; </script> {% endpartial %} {% partial name: "confirmation" %} <h2>Success!</h2> <h3>Thank you, {{ contest_entry.registration.name }} for submitting your entry.</h3> <p>Why not <a href="#" class="share">share</a> your recipe with your friends?</p> <p>Email: {{ contest_entry.registration.email }}</p> <p>Recipe:</p> <div class="recipe">{{contest_entry.submission.recipe | newline_to_br }}</div> <p>Story:</p> <div class="recipe">{{contest_entry.submission.story | newline_to_br }}</div> <p>Main Photo of your recipe: {{ contest_entry.submission.photos.1 | img_tag }}</p> {% if contest_entry.submission.photos.size > 1 %} <div class="photos"> <p>Additional photos:</p> <ul class="photo list"> {% for photo in contest_entry.submission.photos offset:1 %} <li>{{ photo | img_tag }}</li> {% endfor %} </ul> {% endif %} </div> {% capture featuredURL %}{% page_params_link featuredItemId:contest_entry.id %}{% endcapture %} <script> $(document).ready(function() { $('a.share').click(function(event) { sml.ui.Facebook.share({ user_message_prompt: "What is on your mind?", attachment: { name: '{{contest_entry.submission.recipe_name}}', caption: 'A delicious recipe by {{contest_entry.registration.name}}', href: '{{ shareURL }}', description: '{{contest_entry.submission.recipe | truncate::120}}', media: [{ type: 'image', src: '{{contest_entry.submission.photos.first}}', href: '{{ featuredURL }}' }] }, action_links: [{ text: 'Visit My Page', href: '{{ featuredURL }}' }], success: function(post_id) { sml.log("Success!"); }, error: function() { sml.log("Error! "); } }); }) }) </script> {% endpartial %} {% partial name:"featureBox" %} <div class="entryBox"> <h3>{{featuredItem.submission.title}} by {{featuredItem.registration.name}}</a> {% partial name:"bigPhoto" %} {{big | img_tag}} {% endpartial %} <div id="bigPhoto"> {% render partial:"bigPhoto" big:featuredItem.submission.photos.first %} </div> <ul> {% for photo in featuredItem.submission.photos %} <li>{% ajax_link partial:"bigPhoto" div_id:"bigPhoto" big:photo %}{{photo | resize_to:"200"}}{% endajax_link %}</li> {% endfor %} </ul> <div class="recipe"> <h4>{{featuredItem.submission.recipe_name}}</h4> <div class="social"> {% capture featuredURL %}{% page_params_link featuredItemId:featuredItem.id %}{% endcapture %} <div class="votes">{% content_vote featuredItem %}</div> <div class="share">{% share featuredItem href:featuredURL %}</div> </div> {{featuredItem.submission.recipe | newline_to_br }} </div> <div class="recipe_story"> <p>The story behind {{featuredItem.submission.recipe_name}}:</p> {{featuredItem.submission.story | newline_to_br }} </div> <div class="comments"> {% facebook_comments featuredItem %} </div> </div> {% endpartial %} {% partial name: "gallery" %} {% paginate contest.contest_entries per_page:6 order:order_by keywords:category %} {% for entry in contest_entries %} <h4>{% ajax_link partial:"featureBox" featuredItem:entry div_id:"featured" %}{{ entry.submission.recipe_name }}{% endajax_link %}</h4> <p>Submitted by {{ entry.registration.name }}</p> {% ajax_link partial:"featureBox" featuredItem:entry div_id:"featured" %}{{ entry.submission.photos.first | resize_to: "200" | img_tag }}{% endajax_link %} {% content_vote entry %} {% endfor %} {{ pagination_links }} {% endpaginate %} {% endpartial %} <h2>{{contest.title}}</h2> <p>Share your favorite recipes for a chance to be featured in food magazine and win a lifetime supply of sardines!</p> {% contest name:"recipes" %} {% capture start %}{{contest.activated_at | date:"%s"}}{% endcapture %} {% capture end %}{{contest.expired_at | date:"%s"}}{% endcapture %} {% capture whatTime %}{{now | date:"%s"}}{% endcapture %} {% if start < whatTime and end > whatTime %} <p> {% contest_form_link entry_form_partial:"form" success_partial:"confirmation" %} Click here to enter {% endcontest_form_link %} </p> {% elsif start > whatTime %} The {{contest.title}} launches in {{start | count_down_to }}! Come back soon! {% elsif end < whatTime %} <p>We're sorry, {{contest.title}} is no longer active. Check out all the amazing recipes our fans submitted and try one at home tonight!</p> {% endif %} <div class="nav_links"> <ul> <li>{% ajax_link partial: 'gallery' container: 'gallery_container' contest:contest category:"*" order_by:"created_at DESC" %}Newest{% endajax_link %}</li> <li>{% ajax_link partial: 'gallery' container: 'gallery_container' contest:contest category:"*" order_by:"created_at ASC" %}Oldest{% endajax_link %}</li> <li>{% ajax_link partial: 'gallery' container: 'gallery_container' contest:contest category:"*" order_by:"vote_count DESC" %}Most Popular{% endajax_link %}</li> <li>{% ajax_link partial: 'gallery' container: 'gallery_container' contest:contest category:"breakfast" order_by:"created_at DESC" %}Breakfast{% endajax_link %}</li> <li>{% ajax_link partial: 'gallery' container: 'gallery_container' contest:contest category:"lunch" order_by:"created_at DESC" %}Lunch{% endajax_link %}</li> <li>{% ajax_link partial: 'gallery' container: 'gallery_container' contest:contest category:"dinner" order_by:"created_at DESC" %}Dinner{% endajax_link %}</li> <li>{% ajax_link partial: 'gallery' container: 'gallery_container' contest:contest category:"dessert" order_by:"created_at DESC" %}Dessert{% endajax_link %}</li> </ul> <div id="featureBox"> {% if page_params_link.featuredItemId.size >0 %} {% get_content_item myItem content_item_id:page_params.featuredItemId %} {% render partial:"featureBox" featuredItem:myItem %} {{# checks if the page_params_link was used and, if so, grabs the id of the content item that was shared, calls that content item, and pushes it into the featured item display }} {% elsif contest.contest_entries.size > 0 %} {% render partial:"featureBox" featuredItem:contest.contest_entries.first %} {{# shows the newest item as the featured item}} {% else %} There are no entries in this contest yet. Why not be the first? {% endif %} </div> <div id="gallery_container"> {% render partial: "gallery" contest:contest order_by:"created_at DESC" %} </div> {% endcontest %} |
![]() |
Document generated by Confluence on Feb 12, 2013 09:09 |